package org.luxor.common.netty.protocol;

import io.netty.buffer.ByteBuf;

import static io.netty.buffer.ByteBufUtil.*;

/**
 * Netty Codec Util
 *
 * @author Mr.yan @date 2024/2/1
 */
public class NettyCodecUtil {
    public static void main(String[] args) {
        System.out.println(getVariableLengthInt(861));
    }

    public static int getFixedHeaderByte1(NettyFixedHeader fixedHeader) {
        int ret = 0;
        // **** 0000
        ret |= fixedHeader.messageType().value() << 4;
        if (fixedHeader.isDup()) {
            // 0000 *000
            ret |= 0x08;
        }
        // 0000 0**0
        ret |= fixedHeader.qosLevel().value() << 1;
        return ret;
    }

    public static void writeVariableLengthInt(ByteBuf buf, int num) {
        do {
            int digit = num % 128;
            num /= 128;
            if (num > 0) {
                digit |= 0x80;
            }
            buf.writeByte(digit);
        } while (num > 0);
    }

    public static int nullableUtf8Bytes(String s) {
        return s == null ? 0 : utf8Bytes(s);
    }

    public static int nullableMaxUtf8Bytes(String s) {
        return s == null ? 0 : utf8MaxBytes(s);
    }

    public static void writeExactUTF8String(ByteBuf buf, String s, int utf8Length) {
        buf.ensureWritable(utf8Length + 2);
        buf.writeShort(utf8Length);
        if (utf8Length > 0) {
            final int writtenUtf8Length = reserveAndWriteUtf8(buf, s, utf8Length);
            assert writtenUtf8Length == utf8Length;
        }
    }

    public static void writeEagerUTF8String(ByteBuf buf, String s) {
        final int maxUtf8Length = nullableMaxUtf8Bytes(s);
        buf.ensureWritable(maxUtf8Length + 2);
        final int writerIndex = buf.writerIndex();
        final int startUtf8String = writerIndex + 2;
        buf.writerIndex(startUtf8String);
        final int utf8Length = s != null ? reserveAndWriteUtf8(buf, s, maxUtf8Length) : 0;
        buf.setShort(writerIndex, utf8Length);
    }

    public static void writeUnsafeUTF8String(ByteBuf buf, String s) {
        final int writerIndex = buf.writerIndex();
        final int startUtf8String = writerIndex + 2;
        // no need to reserve any capacity here, already done earlier: that's why is Unsafe
        buf.writerIndex(startUtf8String);
        final int utf8Length = s != null ? reserveAndWriteUtf8(buf, s, 0) : 0;
        buf.setShort(writerIndex, utf8Length);
    }

    public static int getVariableLengthInt(int num) {
        int count = 0;
        do {
            num /= 128;
            count++;
        } while (num > 0);
        return count;
    }


}
